package com.photoeditor.demo.model.bean.stash;

import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.RectF;
import android.graphics.Typeface;
import android.text.Layout;
import android.text.SpannableString;
import android.text.StaticLayout;
import android.text.TextPaint;

import com.common.base.ComponentContext;
import com.common.base.utils.DeviceUtils;
import com.photoeditor.R;
import com.photoeditor.demo.model.image.collage.util.MathUtil;
import com.photoeditor.demo.model.image.util.ImageHelper;
import com.photoeditor.demo.ui.widget.stash.container.ContainerView;
import com.photoeditor.demo.util.font.FontHelper;

import static com.photoeditor.demo.model.bean.EditEmojiBean.RADIUS;
import static com.photoeditor.demo.model.bean.stash.StickerBean.SMALLEST_SIZE;

/**
 * Created by Administrator on 2017/6/24 0024.
 */

public class TextBean implements ContainerBean {

    public static final int TEXT_STATE_0 = 0;
    public static final int TEXT_STATE_1 = 1;
    public static final int TEXT_STATE_2 = 2;
    public static final int TEXT_STATE_3 = 3;

    private static final float MAX_WIDTH = ImageHelper.SCREEN_WIDTH * 1.5f;

    private float mMaxWidth = DeviceUtils.getScreenWidthPx(ComponentContext.getContext())
            - DeviceUtils.dip2px(ComponentContext.getContext(), 40);
    //文字的TextPaint
    private TextPaint mTextPaint;

    private Paint mBgPaint;

    private TextPaint mDefaultTextPaint;

    //文字的Rect
    private RectF mTextRect;

    private RectF mButtonRect;
    private RectF mDeleteRect;

    private RectF mLeftOperationRect = new RectF();
    private RectF mTopOperationRect = new RectF();
    private RectF mRightOperationRect = new RectF();
    private RectF mBottomOperationRect = new RectF();

    //文字
    private SpannableString mString;

    //显示文字的区域layout
    private StaticLayout mLayout;

    /**
     * 是否正被点击
     */
    private boolean mIsTouch = false;

    private static final float DEFAULT_PADDING = DeviceUtils.dip2px(ComponentContext.getContext(), 8);

    private static final float DEFAULT_RADIUS = DeviceUtils.dip2px(ComponentContext.getContext(), 4);

    private float mRadius = DEFAULT_RADIUS;

    //文字和框的上下左右的padding
    private float mPadding = DEFAULT_PADDING;

    /**
     * 当前旋转的角度
     */
    private float mDegree = 0;
    private float mRealDegree = 0;

    /**
     * 用于点击位置的映射
     */
    private Matrix mMatrix;

    /**
     * 默认阴影的颜色
     */
    public static final int DEFAULT_COLOR = Color.rgb(0x00, 0x00, 0x00);

    //是不是粗体
    private boolean mIsBold = true;

    //是不是有阴影
    private boolean mIsShadow = false;

    private int mSelectColor = Color.WHITE;

    private int mStyle = TEXT_STATE_0;

    private int mCheckId;

    private String mFontKey = FontHelper.DEFAULT_FONT_PKG_NAME;

    private Bitmap mTextBitmap;

    private Canvas mCanvas;

    private RectF mLastRectBeforeScale = new RectF();

    private boolean mIsInit = false;

    private boolean mIsNeedSave = false;

    /**
     * 一些阴影相关的参数
     */
    public final static int SHADOW_DX = DeviceUtils.dip2px(ComponentContext.getContext(), 0);

    public final static int SHADOW_DY = DeviceUtils.dip2px(ComponentContext.getContext(), 0);

    public final static int SHADOW_RADIUS = DeviceUtils.dip2px(ComponentContext.getContext(), 5);

    public TextBean(String e, RectF mDrawableRect) {
        this(e, mDrawableRect.centerX(), mDrawableRect.centerY());
    }

    public TextBean(String e, float centerX, float centerY) {
        this(e, centerX, centerY, Color.WHITE);
    }

    public TextBean(String e, float centerX, float centerY, int selectColor) {
        if (e != null) {
            mTextPaint = new TextPaint(TextPaint.ANTI_ALIAS_FLAG);
            mTextPaint.setAntiAlias(true);
            mTextPaint.setColor(Color.WHITE);
            mTextPaint.setFakeBoldText(true);
            mTextPaint.setTextSize(DeviceUtils.sp2pxF(ComponentContext.getContext(), 32f));

            mBgPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
            mBgPaint.setStyle(Paint.Style.FILL);

            mString = new SpannableString(e);
            mTextRect = new RectF();
            mButtonRect = new RectF();
            mDeleteRect = new RectF();
            mMatrix = new Matrix();
            initDefaultPaint();
            initData(centerX, centerY);

            update(selectColor, TEXT_STATE_0, e);
        }
    }


    private void initDefaultPaint() {
        mDefaultTextPaint = new TextPaint(TextPaint.ANTI_ALIAS_FLAG);
        mDefaultTextPaint.setAntiAlias(true);
        mDefaultTextPaint.setColor(Color.WHITE);
        mDefaultTextPaint.setTextSize(DeviceUtils.sp2pxF(ComponentContext.getContext(), 32f));
    }

    /**
     * 初始化数据
     */
    public void initData(float centerX, float centerY) {

        float width = 0, height;

        width = StaticLayout.getDesiredWidth(mString, mTextPaint);
        if (width > mMaxWidth) {
            width = mMaxWidth;
        }
        mLayout = new StaticLayout(mString, mTextPaint, (int) (width + 1f), Layout.Alignment.ALIGN_CENTER, 1.0f, 0.0f, false);
        height = mLayout.getHeight();

        mTextRect.left = centerX - width / 2 - mPadding;
        mTextRect.top = centerY - height / 2 - mPadding;
        mTextRect.right = mTextRect.left + width + 2 * mPadding;
        mTextRect.bottom = mTextRect.top + height + 2 * mPadding;

        countOtherRect();
        mLastRectBeforeScale.set(mTextRect);

    }

    public void update(int selectColor, int style, String text) {
        mStyle = style;
        mSelectColor = selectColor;
        mString = new SpannableString(text);
        switch (mStyle) {
            case TEXT_STATE_0:
                mTextPaint.setColor(mSelectColor);
                mDefaultTextPaint.setColor(mSelectColor);

                mBgPaint.setColor(Color.TRANSPARENT);
                break;
            case TEXT_STATE_1:
                if (mSelectColor == Color.WHITE) {
                    mTextPaint.setColor(Color.BLACK);
                    mDefaultTextPaint.setColor(Color.BLACK);
                } else {
                    mTextPaint.setColor(Color.WHITE);
                    mDefaultTextPaint.setColor(Color.WHITE);
                }

                mBgPaint.setColor(mSelectColor);
                break;
            case TEXT_STATE_2:
                mTextPaint.setColor(mSelectColor);
                mDefaultTextPaint.setColor(mSelectColor);

                mBgPaint.setColor(ComponentContext.getContext().getResources().getColor(R.color.text_bg_color_gray));
                break;
            case TEXT_STATE_3:
                mTextPaint.setColor(mSelectColor);
                mDefaultTextPaint.setColor(mSelectColor);

                mBgPaint.setColor(ComponentContext.getContext().getResources().getColor(R.color.text_bg_color_black));
                break;
        }
        doUpdate(true);
    }

    public void updateColor(int textColor, int bgColor) {
        mTextPaint.setColor(textColor);
        mDefaultTextPaint.setColor(textColor);
        mBgPaint.setColor(bgColor);
        doUpdate(true);
    }

    public void updateFont(Typeface typeface, String fontKey) {
        mTextPaint.setTypeface(typeface);
        mDefaultTextPaint.setTypeface(typeface);
        mFontKey = fontKey;
        doUpdate(true);
    }

    public void updateStyle(int style) {
        mStyle = style;
    }

    public void updateCheckId(int checkId) {
        if (checkId >= 0) {
            mCheckId = checkId;
        }
    }

    public int getCheckId() {
        return mCheckId;
    }

    public void update(boolean isBold, boolean isShader, int color, String text) {
        mIsBold = isBold;
        mTextPaint.setFakeBoldText(isBold);
        mDefaultTextPaint.setFakeBoldText(isBold);
        mIsShadow = isShader;
        if (isShader) {
            mTextPaint.setShadowLayer(SHADOW_RADIUS, SHADOW_DX, SHADOW_DY, DEFAULT_COLOR);
            mDefaultTextPaint.setShadowLayer(SHADOW_RADIUS, SHADOW_DX, SHADOW_DY, DEFAULT_COLOR);
        } else {
            mTextPaint.setShadowLayer(0, SHADOW_DX, SHADOW_DY, DEFAULT_COLOR);
            mDefaultTextPaint.setShadowLayer(0, SHADOW_DX, SHADOW_DY, DEFAULT_COLOR);
        }
        mTextPaint.setColor(color);
        mDefaultTextPaint.setColor(color);
        mString = new SpannableString(text);
        doUpdate(true);
    }

    private void doUpdate(boolean isRectChange) {
        if (containsEmoji()) {
            createNewBitmap();
        }

        float width = 0, height;
        width = StaticLayout.getDesiredWidth(mString, mTextPaint);
        if (width > mMaxWidth) {
            width = mMaxWidth;
        }
        mLayout = new StaticLayout(mString, mTextPaint, (int) (width), Layout.Alignment.ALIGN_CENTER, 1.0f, 0.0f, false);
        height = mLayout.getHeight();

        float centerX = mTextRect.centerX();
        float centerY = mTextRect.centerY();

        mTextRect.left = centerX - width / 2 - mPadding;
        mTextRect.top = centerY - height / 2 - mPadding;
        mTextRect.right = mTextRect.left + width + 2 * mPadding;
        mTextRect.bottom = mTextRect.top + height + 2 * mPadding;

        countOtherRect();
        mLastRectBeforeScale.set(mTextRect);

        if (!containsEmoji()) {
            if (mTextBitmap != null) {
                mTextBitmap.recycle();
            }
            int w = (int) mTextRect.width();
            int h = (int) mTextRect.height();
            w = Math.max(1, w);
            h = Math.max(1, h);

            mTextBitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
            mCanvas = new Canvas(mTextBitmap);
            mCanvas.drawRoundRect(new RectF(0, 0, w, h), mRadius, mRadius, mBgPaint);
            mCanvas.translate(mPadding, mPadding);
            mLayout.draw(mCanvas);
        }
    }

    private void createNewBitmap() {
        int width = 0, height;
        width = (int) StaticLayout.getDesiredWidth(mString, mDefaultTextPaint);
        if (width > mMaxWidth) {
            width = (int) mMaxWidth;
        }
        StaticLayout layout = new StaticLayout(mString, mDefaultTextPaint, width, Layout.Alignment.ALIGN_CENTER, 1.0f, 0.0f, false);
        height = layout.getHeight();
        width = Math.max(1, width);
        height = Math.max(1, height);

        if (mTextBitmap != null) {
            mTextBitmap.recycle();
        }
        mTextBitmap = Bitmap.createBitmap(width + (int) (2 * DEFAULT_PADDING), height + (int) (2 * DEFAULT_PADDING), Bitmap.Config.ARGB_8888);
        Canvas canvas = new Canvas(mTextBitmap);
        canvas.drawRoundRect(new RectF(0, 0, width + (int) (2 * DEFAULT_PADDING), height + (int) (2 * DEFAULT_PADDING)), DEFAULT_RADIUS, DEFAULT_RADIUS, mBgPaint);
        canvas.translate(DEFAULT_PADDING, DEFAULT_PADDING);
        layout.draw(canvas);
    }

    @Override
    public void setIsTouch(boolean isTouch) {
        this.mIsTouch = isTouch;
    }

    @Override
    public boolean isTouch() {
        return mIsTouch;
    }

    @Override
    public Matrix getMatrix() {
        mMatrix.setRotate(-mDegree, mTextRect.centerX(), mTextRect.centerY());
        return mMatrix;
    }

    @Override
    public RectF getRect() {
        return mTextRect;
    }

    @Override
    public void setDegree(float degree) {
        mRealDegree += degree;
        float remain = mRealDegree % 90;
        if(Math.abs(remain) >= 0 && Math.abs(remain) < 3) {
            this.mDegree = mRealDegree - remain;
        } else if(Math.abs(remain) > 87) {
            if (remain > 0) {
                this.mDegree = mRealDegree + 90 - remain;
            } else {
                this.mDegree = mRealDegree - 90 - remain;
            }
        } else {
            mDegree = mRealDegree;
        }
    }

    @Override
    public float getDegree() {
        return mDegree;
    }

    @Override
    public void dealScaleAndRotation(float downX, float downY, float nowX, float nowY) {
        float px = mTextRect.centerX();
        float py = mTextRect.centerY();

        float x1 = downX - px;
        float y1 = downY - py;

        float x2 = nowX - px;
        float y2 = nowY - py;

        float scale = (float) (Math.sqrt(x2 * x2 + y2 * y2) / Math.sqrt(x1 * x1 + y1 * y1));

        double degree1 = MathUtil.getDegree(px, py, downX, downY, px + 1, py);

        double degree2 = MathUtil.getDegree(px, py, nowX, nowY, px + 1, py);

        int location1 = MathUtil.getLocation(x1, y1);
        int location2 = MathUtil.getLocation(x2, y2);

        /**
         * 这里是以px, py作为原点   如果是一二象限则 是逆时针旋转  取负值
         *
         * 如果是三四象限则顺时针角度比较小 取正值
         */
        if (location2 == 1 || location2 == 2) {
            degree2 = -degree2;
        }

        if (location1 == 1 || location1 == 2) {
            degree1 = -degree1;
        }

        double degree = degree2 - degree1;

        setScale(scale);
        setDegree((float) degree);
    }

    public Bitmap getTextBitmap() {
        return mTextBitmap;
    }

    @Override
    public void setScale(float scale) {
        Matrix m = new Matrix();
        m.setScale(scale, scale, mTextRect.centerX(), mTextRect.centerY());
        RectF rect = new RectF();
        m.mapRect(rect, mTextRect);

        if (rect.width() >= SMALLEST_SIZE && rect.width() <= MAX_WIDTH) {
            mPadding = mPadding * scale;
            mRadius = mRadius * scale;
            mTextPaint.setTextSize(mTextPaint.getTextSize() * scale);
            mMaxWidth = mMaxWidth * scale;

            float width = StaticLayout.getDesiredWidth(mString, mTextPaint);

            if (width > mMaxWidth) {
                width = mMaxWidth;
            }

            mLayout = new StaticLayout(mString, mTextPaint, (int) (width + 1f), Layout.Alignment.ALIGN_CENTER, 1.0f, 0.0f, false);

            /*float centerX = rect.centerX();
            float centerY = rect.centerY();
            int height = mLayout.getHeight();

            rect.left = centerX - width / 2 - mPadding;
            rect.right = rect.left + width + 2 * mPadding;
            rect.top = centerY - height / 2 - mPadding;
            rect.bottom = rect.top + height + 2 * mPadding;*/

            mTextRect = rect;
            countOtherRect();
            mLastRectBeforeScale.set(mTextRect);

            if (!containsEmoji()) {
                if (mTextBitmap != null) {
                    mTextBitmap.recycle();
                }
                mTextBitmap = Bitmap.createBitmap((int) mTextRect.width(), (int) mTextRect.height(), Bitmap.Config.ARGB_8888);
                mCanvas = new Canvas(mTextBitmap);
                mCanvas.drawRoundRect(new RectF(0, 0, mTextRect.width(), mTextRect.height()), mRadius, mRadius, mBgPaint);
                mCanvas.translate(mPadding, mPadding);
                mLayout.draw(mCanvas);
            }
        }

    }

    @Override
    public void scaleTo(RectF lastRectF, float scale) {
        Matrix m = new Matrix();
        m.setScale(scale, scale, mTextRect.centerX(), mTextRect.centerY());
        m.mapRect(mTextRect, lastRectF);
        countOtherRect();
    }

    @Override
    public void setLastMatrix(Matrix matrix) {
        if (mLastMatrix == null) {
            mLastMatrix = new Matrix();
        }
        mLastMatrix.set(matrix);
    }

    private Matrix mLastMatrix;

    @Override
    public void doScaleMove(RectF baseRect, RectF supperRect, Matrix matrix, Matrix cacheMatrix, RectF viewRect) {
        if (mLastMatrix == null) {
            RectF dstRect = new RectF();
            RectF a = new RectF(mTextRect);
            a.offset(-viewRect.left, -viewRect.top);

            //防止坐标对他的影响
            RectF supperRect1 = new RectF(supperRect);
            supperRect1.offset(-viewRect.left, -viewRect.top);
            //aScale是 baseRect -> supperRect的缩放值
            float bScale = supperRect1.width() / baseRect.width();
            Matrix m = new Matrix();
            m.postScale(bScale, bScale, baseRect.centerX(), baseRect.centerY());
            m.postTranslate(supperRect1.centerX() - baseRect.centerX(), supperRect1.centerY() - baseRect.centerY());
            m.invert(m);

            //matrixA是去掉 从baseRect转换到supperRect后的Matrix
            Matrix matrixA = new Matrix(matrix);
            matrixA.preConcat(m);
            matrixA.mapRect(dstRect, a);

            float scale = dstRect.width() / a.width();
            float dx = dstRect.centerX() - a.centerX();
            float dy = dstRect.centerY() - a.centerY();

            cacheMatrix.reset();
            cacheMatrix.setScale(scale, scale, a.centerX(), a.centerY());
            cacheMatrix.mapRect(dstRect, a);

            dstRect.offset(viewRect.left, viewRect.top);
            dstRect.offset(dx, dy);

            if (mTextRect.width() >= SMALLEST_SIZE && mTextRect.width() <= MAX_WIDTH) {
                doScaleMove(dstRect, scale);
            }

            mLastMatrix = new Matrix();
            mLastMatrix.set(matrix);
        } else {
            RectF dstRect = new RectF();
            RectF a = new RectF(mTextRect);
            a.offset(-viewRect.left, -viewRect.top);

            mLastMatrix.invert(mLastMatrix);
            //matrixA是去掉 从baseRect转换到supperRect后的Matrix
            Matrix matrixA = new Matrix(matrix);
            matrixA.preConcat(mLastMatrix);
            matrixA.mapRect(dstRect, a);

            float scale = dstRect.width() / a.width();
            float dx = dstRect.centerX() - a.centerX();
            float dy = dstRect.centerY() - a.centerY();

            cacheMatrix.reset();
            cacheMatrix.setScale(scale, scale, a.centerX(), a.centerY());
            cacheMatrix.mapRect(dstRect, a);

            dstRect.offset(viewRect.left, viewRect.top);
            dstRect.offset(dx, dy);

            if (mTextRect.width() >= SMALLEST_SIZE && mTextRect.width() <= MAX_WIDTH) {
                doScaleMove(dstRect, scale);
            }
            mLastMatrix.set(matrix);
        }
    }

    private void doScaleMove(RectF rect, float scale) {
        mPadding = mPadding * scale;
        mRadius = mRadius * scale;
        mTextPaint.setTextSize(mTextPaint.getTextSize() * scale);
        mMaxWidth = mMaxWidth * scale;

        float width = StaticLayout.getDesiredWidth(mString, mTextPaint);

        if (width > mMaxWidth) {
            width = mMaxWidth;
        }

        mLayout = new StaticLayout(mString, mTextPaint, (int) (width + 1f), Layout.Alignment.ALIGN_CENTER, 1.0f, 0.0f, false);

        mTextRect = rect;
        countOtherRect();
        mLastRectBeforeScale.set(mTextRect);

        if (!containsEmoji()) {
            if (mTextBitmap != null) {
                mTextBitmap.recycle();
            }
            mTextBitmap = Bitmap.createBitmap((int) mTextRect.width(), (int) mTextRect.height(), Bitmap.Config.ARGB_8888);
            mCanvas = new Canvas(mTextBitmap);
            mCanvas.drawRoundRect(new RectF(0, 0, mTextRect.width(), mTextRect.height()), mRadius, mRadius, mBgPaint);
            mCanvas.translate(mPadding, mPadding);
            mLayout.draw(mCanvas);
        }
    }

    @Override
    public void setDegreeDirect(float degree) {

    }

    @Override
    public void setFlip(boolean horizontal, float value) {

    }

    @Override
    public float getFlipX() {
        return 0;
    }

    @Override
    public float getFlipY() {
        return 0;
    }

    @Override
    public void move(float dx, float dy) {
        mTextRect.offset(dx, dy);
        mButtonRect.offset(dx, dy);
        mDeleteRect.offset(dx, dy);
        mLastRectBeforeScale.offset(dx, dy);
    }

    @Override
    public void moveTo(RectF lastRectF, float dx, float dy) {
        mTextRect.left = lastRectF.left - dx;
        mTextRect.right = lastRectF.right - dx;
        mTextRect.top = lastRectF.top - dy;
        mTextRect.bottom = lastRectF.bottom - dy;
        countOtherRect();
    }

    private boolean containsEmoji() {//真为不含有表情
        int len = mString.length();
        for (int i = 0; i < len; i++) {
            if (isEmojiCharacter(mString.charAt(i))) {
                return true;
            }
        }
        return false;
    }

    private boolean isEmojiCharacter(char codePoint) {
        return !((codePoint == 0x0) ||
                (codePoint == 0x9) ||
                (codePoint == 0xA) ||
                (codePoint == 0xD) ||
                ((codePoint >= 0x20) && (codePoint <= 0xD7FF)) ||
                ((codePoint >= 0xE000) && (codePoint <= 0xFFFD)) ||
                ((codePoint >= 0x10000) && (codePoint <= 0x10FFFF)));
    }

    @Override
    public int getType() {
        return ContainerView.BEAN_TYPE_TEXT;
    }

    @Override
    public RectF getLastRectBeforeScale() {
        return mLastRectBeforeScale;
    }

    @Override
    public Bitmap getBitmap() {
        return mTextBitmap;
    }

    @Override
    public void onDestroy() {
        if (mTextBitmap != null) {
            mTextBitmap.recycle();
        }
    }

    private void countOtherRect() {
        mButtonRect.left = mTextRect.right - RADIUS;
        mButtonRect.top = mTextRect.bottom - RADIUS;
        mButtonRect.right = mTextRect.right + RADIUS;
        mButtonRect.bottom = mTextRect.bottom + RADIUS;

        mDeleteRect.left = mTextRect.left - RADIUS;
        mDeleteRect.top = mTextRect.top - RADIUS;
        mDeleteRect.right = mTextRect.left + RADIUS;
        mDeleteRect.bottom = mTextRect.top + RADIUS;

    }

    @Override
    public RectF getButtonRect() {
        return mButtonRect;
    }

    @Override
    public RectF getSettingRect() {
        return null;
    }

    @Override
    public RectF getDeleteRect() {
        return mDeleteRect;
    }

    @Override
    public RectF getLeftOperationRect() {
        return mLeftOperationRect;
    }

    @Override
    public RectF getTopOperationRect() {
        return mTopOperationRect;
    }

    @Override
    public RectF getRightOperationRect() {
        return mRightOperationRect;
    }

    @Override
    public RectF getBottomOperationRect() {
        return mBottomOperationRect;
    }

    @Override
    public void operationLeft(float dx) {

    }

    @Override
    public void operationRight(float dx) {

    }

    @Override
    public void operationTop(float dy) {

    }

    @Override
    public void operationBottom(float dy) {

    }

    public float getPadding() {
        return mPadding;
    }

    public boolean isBold() {
        return mIsBold;
    }

    public boolean isShadow() {
        return mIsShadow;
    }

    public int getColor() {
        return mSelectColor;
    }

    public int getStyle() {
        return mStyle;
    }

    public String getString() {
        return mString.toString();
    }

    public StaticLayout getLayout() {
        return mLayout;
    }

    public TextPaint getPaint() {
        return mTextPaint;
    }

    /**
     * 更新String
     *
     * @param s
     */
    public void updateString(String s) {
        mString = new SpannableString(s);
        doUpdate(true);
    }

    /**
     * 更新color
     *
     * @param color
     */
    public void updateColor(int color) {
        mTextPaint.setColor(color);
        doUpdate(false);
    }

    /**
     * 设置Bold
     *
     * @param isBold
     */
    public void updateBold(boolean isBold) {
        mIsBold = isBold;
        mTextPaint.setFakeBoldText(isBold);
        doUpdate(false);
    }

    /**
     * 设置阴影
     *
     * @param isShader
     */
    public void updateShadow(boolean isShader) {
        mIsShadow = isShader;
        if (isShader) {
            mTextPaint.setShadowLayer(SHADOW_RADIUS, SHADOW_DX, SHADOW_DY, DEFAULT_COLOR);
        } else {
            mTextPaint.setShadowLayer(0, SHADOW_DX, SHADOW_DY, DEFAULT_COLOR);
        }
        doUpdate(false);
    }

    public String getFontKey() {
        return mFontKey;
    }

    public boolean isNeedSave() {
        return mIsNeedSave;
    }

    public void setIsNeedSave(boolean isNeedSave) {
        this.mIsNeedSave = isNeedSave;
    }
}
